home *** CD-ROM | disk | FTP | other *** search
/ NetNews Offline 2 / NetNews Offline Volume 2.iso / news / comp / lang / c++-part1 / 9012 < prev    next >
Encoding:
Text File  |  1996-08-05  |  8.6 KB  |  330 lines

  1. Path: cleveland.Freenet.Edu!bf461
  2. From: bf461@cleveland.Freenet.Edu (Bryan Murphy)
  3. Newsgroups: comp.lang.c++
  4. Subject: C++ OO question (long)
  5. Date: 28 Feb 1996 00:51:38 GMT
  6. Organization: Case Western Reserve University, Cleveland, OH (USA)
  7. Message-ID: <4h08uq$mve@madeline.INS.CWRU.Edu>
  8. Reply-To: bf461@cleveland.Freenet.Edu (Bryan Murphy)
  9. NNTP-Posting-Host: owl.ins.cwru.edu
  10.  
  11.  
  12.  
  13. /*
  14. Warning:  This is a long one. 
  15.  
  16. Ok, I'm fairly new to the C++ programming paradigm.  While I've 
  17. quite a bit of experience with the C++ syntax, I've only just
  18. begun to understand the concepts that really go into an OOP 
  19. program.  
  20.  
  21. Anyways, I have to write a program for a class, all it needs to
  22. do is multiply two matrices together, but I decided to brush up
  23. on my C++ and to forgoe using ada or pascal to  just throw some-
  24. thing together. 
  25.  
  26. Bellow is the program I wrote.  It implements a class called 
  27. Matrix, which allocates memory on the heap for the storage of
  28. a matrix of XxY dimensions.  It also implements a copy constructor
  29. for assignment, and a couple of different mathematical operations
  30. to be performed on the matrix.
  31.  
  32. I've got one big problem, and one little one, even though this
  33. does compile and run fine the way it is (I'm compiling this as
  34. a Visual C++ 4.0 Console Application).
  35.  
  36. The first problem involves this very peculiar inconsistency that
  37. I can't explain, for instance, this works:
  38.  
  39.           Matrix M3 = Matrix1 * Matrix2;
  40.  
  41. whereas defining Matrix M3 ahead of time
  42.  
  43.           M3 = Matrix1 * Matrix2;
  44.  
  45. crashes out on me giving me an error.  I can't really tell why.
  46. It's a memory allocation assertion error.  I can't figure out
  47. why I can't do the second method.  I was thinking about this, 
  48. and I have another question related to this.  When I define
  49. the Matrix M3 and assign it right away, is the Default Blank
  50. Constructor called, THEN the Copy Constructor?  Or just the
  51. copy constructor?  Also, say the copy Constructor was called.
  52. When the new data is copied over, is the Destructor called 
  53. before the copy constructor is used to copy the new data over?
  54. I think these questions could definately shed some light as to
  55. the inconsistency noted above.
  56.  
  57. Also, my second problem is pretty simple.  It relates to using
  58. variable arguments.  Is there anything peculiar or different
  59. about Visual C++'s variable arguments?  I was trying to initialize
  60. the Matrices by using variable arguments, rather than passing
  61. a pointer to an array of Integers, but I could not get the
  62. constructor to get the proper numbers.  I was basing the code
  63. EXACTLY like what was in my C++ for Pascal Programmers book, 
  64. nearly statement by statement, but it didn't work.  Visual C++
  65. accepted the syntax, and everything looked ok, but I was just
  66. not getting the right values.
  67.  
  68. Here is the CPP file.  It's one file and can be copied.  I even
  69. commented out this text so you can just save the message to
  70. a file and copy it directly if you would like to take a look at 
  71. it.
  72.  
  73. Any help would be GREATLY appreciated!
  74. */
  75.  
  76. /******************************************************************
  77.   
  78.   Author:   Bryan Murphy
  79.   Class:    CPS 341
  80.   Teacher:    Y. Pan
  81.   Due Date: Monday 3/4/96
  82.  
  83.   This program implements a Matrix class and the appropriate
  84.   Multiplication and Division functions for that class.  The
  85.   program then demonstrates the use of this class.
  86.  
  87. ******************************************************************/
  88. #include "iostream.h"
  89. #include "stdarg.h"
  90. #include "stdlib.h"
  91.  
  92. class Matrix {
  93. public:
  94.     Matrix();                        // Constructor
  95.     Matrix(int,int,int const *);    // Constructor
  96.     ~Matrix();                        // Destructor
  97.  
  98.     Matrix(const Matrix &);            // Copy Constructor
  99.  
  100.     int GetData(int,int);            // Get Number from Matrix
  101.     void SetData(int,int,int);        // Set a Value in the Matrix
  102.     void Display(void);                // Display Contents of Matrix
  103.  
  104.     int Xdim()    { return xdim+1; }  // In case the size needs
  105.     int Ydim()  { return ydim+1; }  // to be checked.
  106.  
  107.     // The following are the operations that can be
  108.     // performed on a matrix.
  109.     friend Matrix operator * (Matrix, Matrix);    // Matrix *
  110.     friend Matrix operator * (Matrix, int);        // Scalar *
  111.     friend Matrix operator + (Matrix, Matrix);    // Matrix +
  112.     friend Matrix operator - (Matrix, Matrix);    // Matrix -
  113.         
  114. private:
  115.  
  116.     int    xdim;                        // X size of Matrix
  117.     int    ydim;                        // Y size of Matrix
  118.  
  119.     int    *MatrixData;                // Contents of Matrix
  120. };
  121.  
  122.  
  123. // Matrix Constructor.  This constructor initializes the
  124. // matrix and allocates memory for the matrix data.
  125. Matrix::Matrix(int x, int y, int const *data = 0)
  126. {
  127.     // Set matrix size (numbering system 0 to X-1)
  128.     xdim = (x-1);
  129.     ydim = (y-1);
  130.  
  131.     // Allocate memory for matrix
  132.     MatrixData = new int[x*y];
  133.  
  134.     // Check for memory allocation error
  135.     if (MatrixData == 0) throw "Memory Allocation Error";
  136.  
  137.     // Copy Data to Matrix if Available
  138.     if (data !=0) 
  139.         for (int i=0; i<x*y; i++) MatrixData[i] = data[i];
  140.     else
  141.         for (int i=0; i<x*y; i++) MatrixData[i] = 0;
  142.  
  143. }
  144.  
  145. // This constructor is for special cases where we don't
  146. // know what the resulting member will look like.
  147. Matrix::Matrix()
  148. {
  149.     xdim = 0;
  150.     ydim = 0;
  151.     MatrixData = 0;
  152. }
  153.  
  154. // Matrix Destructor.  Clean up the mess.
  155. Matrix::~Matrix()
  156. {
  157.     // Free up the memory used
  158.     delete MatrixData;
  159. }
  160.  
  161. // This is used for copying and assignment (ie. Matrx = Matrx2;)
  162. Matrix::Matrix(const Matrix &Mat)
  163. {
  164.     int size = (Mat.xdim+1)*(Mat.ydim+1);
  165.     MatrixData = new int[size];
  166.  
  167.     xdim = Mat.xdim;
  168.     ydim = Mat.ydim;
  169.  
  170.     // Copy the Data over
  171.     for (int i=0; i<size; i++) MatrixData[i] = Mat.MatrixData[i];
  172.     
  173. }
  174.  
  175. // This function is used to get a specific value from a 
  176. // matrix in position (x,y)
  177. int Matrix::GetData(int x,int y)
  178. {
  179.     // Convert to matrix indices
  180.     x--; 
  181.     y--;
  182.  
  183.     // Make sure X and Y are within bounds
  184.     if (x<0 || x>xdim) throw("X out of Matrix Bounds");
  185.     if (y<0 || y>ydim) throw("Y out of Matrix Bounds");
  186.     
  187.     // Return Value if no Exceptions Raised
  188.     return MatrixData[y+x*(ydim+1)];    
  189. }
  190.  
  191. // Set a value in a Matrix
  192. void Matrix::SetData(int x,int y,int value)
  193. {
  194.     // Convert to matrix indices
  195.     x--; 
  196.     y--;
  197.  
  198.     // Make sure X and Y are within bounds
  199.     if (x<0 || x>xdim) throw("X out of Matrix Bounds");
  200.     if (y<0 || y>ydim) throw("Y out of Matrix Bounds");
  201.  
  202.     MatrixData[y+x*(ydim+1)] = value;
  203. }
  204.  
  205. // Display the Contents of the Matrix
  206. void Matrix::Display(void)
  207. {
  208.     // Just in Case...
  209.     if (MatrixData == 0) throw("Internal Matrix Error!");
  210.  
  211.     cout << xdim+1 << "x" << ydim+1 << " Matrix" << endl;
  212.  
  213.     // Display Matrix
  214.     for (int x=0; x<=xdim; x++)
  215.     {
  216.         for (int y=0; y<=ydim; y++)
  217.         {
  218.             // For Formatting Purposes
  219.             if (MatrixData[y+x*(ydim+1)] < 10)
  220.                 cout << " ";
  221.  
  222.             cout << " " << MatrixData[y+x*(ydim+1)];
  223.         }
  224.         cout << endl;
  225.     }
  226. }
  227.  
  228.  
  229. // * operator for Matrices
  230. Matrix operator * (Matrix M1, Matrix M2)
  231. {
  232.     // M1 columns must equal M2 rows
  233.     if (M1.ydim != M2.xdim)
  234.         throw "Matrices cannnot be multiplied!";
  235.  
  236.     Matrix M3(M1.xdim+1,M2.ydim+1);
  237.  
  238.     // Do the Multiplication
  239.     for (int i=1; i<M1.Xdim(); i++)
  240.         for (int j=1; j<M2.Ydim(); j++)
  241.         {
  242.             M3.SetData(i,j,0);
  243.             for (int k=1; k<M2.Xdim(); k++)
  244.                 M3.SetData(i,j,M3.GetData(i,j)+
  245.                                M1.GetData(i,k)*M2.GetData(k,j));
  246.         }
  247.  
  248.     return M3;
  249. }
  250.  
  251. // This is for multiplication by a Scalar
  252. Matrix operator * (Matrix M1, int Scalar)
  253. {
  254.     Matrix Temp(M1.xdim+1,M1.ydim+1);
  255.     int size = (M1.xdim+1)*(M1.ydim+1);
  256.  
  257.     // Multiply matrix by scalar
  258.     for (int i=0; i<size; i++) 
  259.         Temp.MatrixData[i] = M1.MatrixData[i] * Scalar;
  260.  
  261.     return Temp;
  262. }
  263.  
  264. // Add two Matrices together
  265. Matrix operator + (Matrix M1, Matrix M2)
  266. {
  267.     // Matrices must be same dimensions
  268.     if ((M1.xdim != M2.xdim)||(M1.ydim != M2.ydim))
  269.         throw "Matrices cannot be added!";
  270.  
  271.     Matrix Temp(M1.xdim+1,M1.ydim+1);
  272.     int size = (M1.xdim+1)*(M1.ydim+1);
  273.  
  274.     // Do the addition
  275.     for (int i=0; i<size; i++)
  276.         Temp.MatrixData[i] = M1.MatrixData[i] + M2.MatrixData[i];
  277.  
  278.     return Temp;
  279. }
  280.  
  281. // Subtract two Matrices
  282. Matrix operator - (Matrix M1, Matrix M2)
  283. {
  284.     // Matrices must be same dimensions
  285.     if ((M1.xdim != M2.xdim)||(M1.ydim != M2.ydim))
  286.         throw "Matrices cannot be subtracted!";
  287.  
  288.     Matrix Temp(M1.xdim+1,M1.ydim+1);
  289.     int size = (M1.xdim+1)*(M1.ydim+1);
  290.  
  291.     // Do the Subtraction
  292.     for (int i=0; i<size; i++)
  293.         Temp.MatrixData[i] = M1.MatrixData[i] - M2.MatrixData[i];
  294.  
  295.     return Temp;
  296. }
  297.  
  298. // Define matrix data as arrays
  299. int        Mat4x4a[16] = {1, 2, 3, 4,
  300.                        5, 6, 7, 8,
  301.                        9, 10,11,12,
  302.                        13,14,15,16};
  303.  
  304. int        Mat4x4b[16] = {0, 1, 1, 1,
  305.                         1, 0, 1, 1,
  306.                        1, 1, 0, 1,
  307.                        1, 1, 1, 0};
  308.  
  309. main() 
  310. {
  311.     // Define Two Matrix Variables
  312.     Matrix M1(4,4, Mat4x4a);
  313.     Matrix M2(4,4, Mat4x4b);
  314.  
  315.     // Test Matrix Operations
  316.     Matrix M3 = M1 * M2;
  317.     Matrix M4 = M2 * M1;
  318.     Matrix M5 = M1 + M2;
  319.  
  320.     // Print out the Results
  321.     cout << "Matrix A:"   << endl; M1.Display();
  322.     cout << "Matrix B:"   << endl; M2.Display();
  323.     cout << "Matrix A*B:" << endl; M3.Display();
  324.     cout << "Matrix B*A:" << endl; M4.Display();
  325.     cout << "Matrix A+B:" << endl; M5.Display();
  326.  
  327.     return 0;
  328. }
  329. -- 
  330.